﻿Imports System.Reflection
Imports System.Windows.Forms
Imports System.Drawing

Public Class Diagram
    Inherits Panel
    Private M_DiagramFile As String
    Private M_DeviceList As DeviceList
    Private M_Mode As EditMode
    Private M_DiagramName As String
    Private M_BackColor As System.Drawing.Color = Color.Silver
    Private M_GridColor As System.Drawing.Color = Color.Black
    Private M_Resources As ResourceManager
    Public Event ModeChanged(ByVal Mode As EditMode)
    Public Enum EditMode
        Locked = 0
        Unlocked = 1
    End Enum
    Public Property Resources() As ResourceManager
        Get
            Return M_Resources
        End Get
        Set(ByVal value As ResourceManager)
            M_Resources = value
        End Set
    End Property
    Public Property DiagramName() As String
        Get
            Return M_DiagramName
        End Get
        Set(ByVal value As String)
            M_DiagramName = value
            Panel1.DiagramName = value
            DiagramDisplay1.DiagramName = value
            Try
                Dim X As TabPage = Me.Parent
                X.Text = M_DiagramName
            Catch
            End Try

        End Set
    End Property

    Public Property Mode() As EditMode
        Get
            Return M_Mode
        End Get
        Set(ByVal value As EditMode)
            M_Mode = value
            Panel1.Mode = M_Mode
            DiagramDisplay1.Mode = M_Mode
        End Set
    End Property
    Public Property BackgroundColor() As System.Drawing.Color
        Get
            Return M_BackColor
        End Get
        Set(ByVal value As System.Drawing.Color)
            M_BackColor = value
            Panel1.BackgroundColor = M_BackColor
            DiagramDisplay1.BackgroundColor = M_BackColor
        End Set
    End Property
    Public Property GridColor() As System.Drawing.Color
        Get
            Return M_GridColor
        End Get
        Set(ByVal value As System.Drawing.Color)
            M_GridColor = value
            Panel1.GridColor = M_GridColor
            DiagramDisplay1.GridColor = M_GridColor
        End Set
    End Property
    Protected Overrides Sub OnMouseWheel(ByVal e As MouseEventArgs)
        Dim mwe As HandledMouseEventArgs = DirectCast(e, HandledMouseEventArgs)
        mwe.Handled = True
    End Sub
    Public Property ShowGrid() As Boolean
        Get
            Return Panel1.ShowGrid
        End Get
        Set(ByVal value As Boolean)
            Panel1.ShowGrid = value
            Me.Refresh()
        End Set
    End Property

    'Add control From Type
    Public Sub AddControl(ByVal Ctrl As Control)
        Dim TP As Type = Ctrl.GetType
        Dim C As Integer = 1
        Dim ok As Boolean = True
        Do
            ok = True
            For Each E As Control In Panel1.Controls
                If E.GetType.Equals(TP) Then
                    If E.Name = TP.Name & C.ToString Then
                        C = C + 1
                        ok = False
                        Exit For
                    End If
                End If
            Next
        Loop Until ok = True

        Ctrl.Name = TP.Name & C.ToString
        Ctrl.SuspendLayout()
        Ctrl.Visible = False
        Panel1.Controls.Add(Ctrl)
        Panel1.GetSockEvents(Ctrl)
        Ctrl.Left = (Me.Width / 2) - (Me.Width / 2)
        Ctrl.Top = (Me.Height / 2) - (Me.Height / 2)
        Ctrl.BringToFront()
        Ctrl.ResumeLayout()
        Ctrl.Visible = True

    End Sub
    'Add Control from Name
    Public Sub AddControlFromName(ByVal TypeName As String, Optional ByVal Left As Integer = 0, Optional ByVal Top As Integer = 0, Optional ByVal Name As String = "", Optional ByVal Settings As String = "")
        Dim Ctrl As Control = M_DeviceList.GetDevice(TypeName.Substring(TypeName.LastIndexOf(".") + 1))
        If Ctrl IsNot Nothing Then
            Dim TP As Type = Ctrl.GetType
            Ctrl.SuspendLayout()
            Ctrl.Visible = False
            Panel1.Controls.Add(Ctrl)
            Panel1.GetSockEvents(Ctrl)

            If Left = 0 And Top = 0 Then
                Ctrl.Left = (Me.Width / 2) - (Me.Width / 2)
                Ctrl.Top = (Me.Height / 2) - (Me.Height / 2)
            Else
                Ctrl.Left = Left
                Ctrl.Top = Top
            End If
            If Name > "" Then
                Ctrl.Name = Name
            Else
                Dim C As Integer = 1
                Dim ok As Boolean = True
                Do
                    ok = True
                    For Each E As Control In Me.Controls
                        If E.GetType.Equals(TP) Then
                            If E.Name = TP.Name & C.ToString Then
                                C = C + 1
                                ok = False
                                Exit For
                            End If
                        End If
                    Next
                Loop Until ok = True
                Ctrl.Name = TP.Name & C.ToString
            End If
            Ctrl.BringToFront()
            Ctrl.ResumeLayout()
            Ctrl.Visible = True
            If Settings > "" Then
                If Ctrl.GetType.GetInterface("I_LoadSave", True) IsNot Nothing Then
                    Dim I As I_LoadSave = Ctrl
                    I.SetSettings(Settings)
                End If
            End If
            Exit Sub
        Else
            MsgBox("Device not found : " & TypeName)
        End If
    End Sub

    Private Sub DiagramDisplay1_BackgroundColor(ByVal NewColor As System.Drawing.Color) Handles DiagramDisplay1.NewBackgroundColor
        M_BackColor = NewColor
        Panel1.BackgroundColor = NewColor
    End Sub
    Private Sub DiagramDisplay1_Clear() Handles DiagramDisplay1.Clear
        ClearDiagram()
    End Sub
    Public Sub ClearDiagram()
        For Each C As Control In Panel1.Controls
            If C.GetType().GetInterface("I_CloseNotify", True) IsNot Nothing Then
                Dim S As I_CloseNotify = C
                S.ShutDown()
            End If
        Next
        Panel1.Controls.Clear()
    End Sub
    Private Sub DiagramDisplay1_GridColor(ByVal NewColor As System.Drawing.Color) Handles DiagramDisplay1.NewGridColor
        M_GridColor = NewColor
        Panel1.GridColor = NewColor
    End Sub
    Private Sub DiagramDisplay1_NameChanged(ByVal Name As String) Handles DiagramDisplay1.NameChanged
        M_DiagramName = Name
        Panel1.DiagramName = Name
        Try
            Dim X As TabPage = Me.Parent
            X.Text = M_DiagramName
        Catch
        End Try
    End Sub
    Public Sub SaveAsDevice(ByVal MacroName As String, ByVal Device As String, ByVal Menu As String)
        Dim FN As String = System.IO.Path.Combine(M_Resources.MacroPath, MacroName & ".Mac")
        Dim FS As New IO.FileStream(FN, IO.FileMode.Create)
        Dim Writer As New IO.StreamWriter(FS)
        Writer.WriteLine("[UserDevice]")
        Writer.WriteLine("Name=" & MacroName)
        Writer.WriteLine("Menu=" & Menu)
        Writer.WriteLine("")
        For Each C As Control In Panel1.Controls
            If C.GetType().GetInterface("I_LoadSave", True) IsNot Nothing Then
                If C.Name = Device Then
                    Writer.WriteLine("[Control]")
                    Writer.WriteLine("Type=" & C.GetType.ToString)
                    Writer.WriteLine("Left=" & C.Left)
                    Writer.WriteLine("Top=" & C.Top)
                    Writer.WriteLine("Name=" & C.Name)
                    Dim S As I_LoadSave = C
                    Writer.WriteLine("Settings=" & S.GetSettings)
                    Writer.WriteLine("")
                End If
            End If
        Next
        Writer.Close()
    End Sub

    Private Sub SaveDiagram(ByVal File As String)
        Dim FS As New IO.FileStream(File, IO.FileMode.Create)
        Dim Writer As New IO.StreamWriter(FS)

        Writer.WriteLine("[Diagram]")
        Writer.WriteLine("Name=" & M_DiagramName)
        Writer.WriteLine("ShowGrid=" & Panel1.ShowGrid.ToString)
        Writer.WriteLine("GridColor=" & Panel1.GridColor.ToArgb)
        Writer.WriteLine("BackColor=" & Panel1.BackColor.ToArgb)
        Writer.WriteLine("Mode=" & M_Mode)
        Writer.WriteLine("")

        For Each C In Panel1.Controls
            If C.GetType().GetInterface("I_LoadSave", True) IsNot Nothing Then
                Writer.WriteLine("[Control]")
                Writer.WriteLine("Type=" & C.GetType.ToString)
                Writer.WriteLine("Left=" & C.Left)
                Writer.WriteLine("Top=" & C.Top)
                Writer.WriteLine("Name=" & C.Name)
                Dim S As I_LoadSave = C
                Writer.WriteLine("Settings=" & S.GetSettings)
                Writer.WriteLine("")
            End If
        Next
        For Each C As Control In Panel1.Controls
            If C.GetType().GetInterface("I_LoadSave", True) IsNot Nothing Then
                For Each CC In C.Controls
                    If TypeOf CC Is Socket Then
                        Dim Sock As Socket = CC
                        If Sock.SocketDirection = Socket.Socket_Direction.Output Then
                            Dim L As String
                            Dim LP As String
                            If Sock.Connected Then
                                L = C.Name & "." & Sock.Name & " ---> " & Sock.Remote.Parent.Name & "." & Sock.Remote.Name
                                LP = Sock.GetLinePoints
                            Else
                                L = C.Name & "." & Sock.Name & " ---> NC"
                                LP = ""
                            End If
                            Writer.WriteLine("[Connection]")
                            Writer.WriteLine(L)
                            Writer.WriteLine(LP)
                            Writer.WriteLine("")
                        End If
                    End If
                Next
            End If
        Next

        Writer.Close()
    End Sub
    Public Sub LoadUserDevice(ByVal DeviceFileName As String)

        Dim FS As New IO.FileStream(IO.Path.Combine(M_Resources.MacroPath, DeviceFileName), IO.FileMode.Open)
        Dim Reader As New IO.StreamReader(FS)

        Dim Com As String

        Dim Typ As String
        Dim Left As String
        Dim Top As String
        Dim Name As String
        Dim Settings As String
        Dim blank As String
        Do While Reader.EndOfStream = False
            Com = Reader.ReadLine()
            If Com = "[Control]" Then
                Typ = Reader.ReadLine.Substring(5)
                Left = Reader.ReadLine.Substring(5)
                Top = Reader.ReadLine.Substring(4)
                Left = 0
                Top = 0
                Name = Reader.ReadLine.Substring(5)
                Settings = Reader.ReadLine.Substring(9)
                blank = Reader.ReadLine
                AddControlFromName(Typ, Left, Top, Name, Settings)
            End If
        Loop
        Reader.Close()
    End Sub
    Private Sub LoadDiagram(ByVal File As String, Optional ByVal Clear As Boolean = True)

        Dim FS As New IO.FileStream(File, IO.FileMode.Open)
        Dim Reader As New IO.StreamReader(FS)

        Dim Com As String

        Dim Typ As String
        Dim Left As String
        Dim Top As String
        Dim Name As String
        Dim Settings As String
        Dim blank As String
        Dim Wire As String
        Dim WireConnections As String

        Do While Reader.EndOfStream = False
            Com = Reader.ReadLine()
            If Com = "[Diagram]" Then
                M_DiagramName = Reader.ReadLine.Substring(5)

                If Reader.ReadLine.Contains("True") Then
                    Panel1.ShowGrid = True
                Else
                    Panel1.ShowGrid = False
                End If

                M_GridColor = Color.FromArgb(Reader.ReadLine.Substring(10))
                Panel1.GridColor = M_GridColor
                DiagramDisplay1.GridColor = M_GridColor

                M_BackColor = Color.FromArgb(Reader.ReadLine.Substring(10))
                Panel1.BackgroundColor = M_BackColor
                DiagramDisplay1.BackgroundColor = M_BackColor

                If Reader.ReadLine.Contains("0") Then
                    M_Mode = 0
                Else
                    M_Mode = 1
                End If

                blank = Reader.ReadLine
                Panel1.DiagramName = M_DiagramName
                DiagramDisplay1.DiagramName = M_DiagramName

            End If
            If Com = "[Control]" Then
                Typ = Reader.ReadLine.Substring(5)
                Left = Reader.ReadLine.Substring(5)
                Top = Reader.ReadLine.Substring(4)
                Name = Reader.ReadLine.Substring(5)
                Settings = Reader.ReadLine.Substring(9)
                blank = Reader.ReadLine
                AddControlFromName(Typ, Left, Top, Name, Settings)
            End If
            If Com = "[Connection]" Then
                Wire = Reader.ReadLine
                WireConnections = Reader.ReadLine
                blank = Reader.ReadLine
                Dim Parts As String() = Wire.Split(" ---> ")
                Dim Dev1 As String = Parts(0)
                Dim Dev2 As String = Parts(2)
                If Dev2 <> "NC" Then
                    Dim DevPartsA As String() = Dev1.Split(".")
                    Dim ParentNameA As String = DevPartsA(0)
                    Dim SocketNameA As String = DevPartsA(1)
                    Dim DevPartsB As String() = Dev2.Split(".")
                    Dim ParentNameB As String = DevPartsB(0)
                    Dim SocketNameB As String = DevPartsB(1)
                    Dim SockA As Socket = Nothing
                    Dim SockB As Socket = Nothing
                    'Sock A
                    For Each C As Control In Panel1.Controls
                        If C.Name = ParentNameA Then
                            For Each CC As Control In C.Controls
                                If CC.Name = SocketNameA Then
                                    SockA = CC
                                    Exit For
                                End If
                            Next
                        End If
                        If SockA IsNot Nothing Then Exit For
                    Next
                    'Sock B
                    For Each C As Control In Panel1.Controls
                        If C.Name = ParentNameB Then
                            For Each CC As Control In C.Controls
                                If CC.Name = SocketNameB Then
                                    SockB = CC
                                    Exit For
                                End If
                            Next
                        End If
                        If SockB IsNot Nothing Then Exit For
                    Next

                    If SockA IsNot Nothing And SockB IsNot Nothing Then
                        SockA.ConnectTo(SockB, WireConnections)
                    End If
                End If
            End If

        Loop
        Reader.Close()


    End Sub

    Private Sub DiagramDisplay1_OpenFile() Handles DiagramDisplay1.OpenFile
        If OpenFileDialog1.ShowDialog = DialogResult.OK Then
            M_DiagramFile = OpenFileDialog1.FileName
            LoadDiagram(OpenFileDialog1.FileName)
        End If
    End Sub

    Private Sub DiagramDisplay1_SaveAsFile() Handles DiagramDisplay1.SaveAsFile
        If SaveFileDialog1.ShowDialog = DialogResult.OK Then
            SaveDiagram(SaveFileDialog1.FileName)
            M_DiagramFile = SaveFileDialog1.FileName
        End If

    End Sub
    Private Sub DiagramDisplay1_SaveFile() Handles DiagramDisplay1.SaveFile
        If M_DiagramFile = "" Then
            If SaveFileDialog1.ShowDialog = DialogResult.OK Then
                SaveDiagram(SaveFileDialog1.FileName)
                M_DiagramFile = SaveFileDialog1.FileName
            End If
        Else
            SaveDiagram(M_DiagramFile)
        End If
    End Sub
    Public Sub SetDeviceList(ByVal DeviceList As DeviceList)
        M_DeviceList = DeviceList
    End Sub

    Private Sub DiagramDisplay1_SetMode(ByVal Mode As DiagramDisplay.EditMode) Handles DiagramDisplay1.SetMode
        M_Mode = Mode
        Panel1.Mode = Mode
        RaiseEvent ModeChanged(Mode)
    End Sub

    Private Sub DiagramDisplay1_ToggleGrid() Handles DiagramDisplay1.ToggleGrid
        If Panel1.ShowGrid = True Then
            Panel1.ShowGrid = False
        Else
            Panel1.ShowGrid = True
        End If
    End Sub
    Public ReadOnly Property Devices() As ControlCollection
        Get
            Return Panel1.Controls
        End Get
    End Property
End Class
